home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir39 / cdpath12.zip / KCD.C < prev    next >
C/C++ Source or Header  |  1993-08-07  |  7KB  |  227 lines

  1. /* Program kcd.c
  2. **
  3. ** Change Directory for 4DOS
  4. **
  5. ** Original code by: ?
  6. **
  7. ** Modified and corrected by S. E. Kohn
  8. **
  9. ** Requires 4DOS environmental variable CDPATH be set to list of
  10. ** primary directories to search.
  11. ** Program will work for partial directory names
  12. **
  13. ** Use 4DOS alias   cd=`<drive>:\<directory>\kcd.com`
  14. **
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <dos.h>
  19. #include <direct.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22.  
  23. #define  CDPATH  "CDPATH"
  24. #define  MAX_DIR 66
  25. #define  PROG    "cd"
  26.  
  27. /* ##################### IS_ROOT_DIR ######################## */
  28. int is_root_dir (char try[])
  29. {
  30.     char *ptr;
  31.  
  32.     if ((ptr = strchr(try, ':')) != NULL)
  33.         ptr++;
  34.     else
  35.         ptr = try;
  36.     if (strchr("\\/", *ptr) != NULL && *(ptr+1) == '\0')
  37.         return 1;
  38.     if (strchr("\\/", *ptr) != NULL && *(ptr+1) == '.' && *(ptr+2) == '\0')
  39.         return 1;
  40.     return 0;
  41. }
  42.  
  43. /* ####################### ISDIR ##################### */
  44. int isdir (char try[])
  45. {
  46.     struct find_t find;
  47.     char *ptr, test[MAX_DIR];
  48.  
  49.     if (is_root_dir(try))
  50.         return 1;
  51.     if ((_dos_findfirst(try, 0xffff, &find) == 0) && (find.attrib & _A_SUBDIR))
  52.          return 1;
  53.     strcpy(test, try);
  54.     strcat(test, "*");
  55.     if (_dos_findfirst(test, 0xffff, &find) == 0)
  56.     {
  57.         if (find.attrib & _A_SUBDIR)
  58.         {
  59.             ptr = strrchr(try, '\\');
  60.             if (ptr != (char *)NULL)
  61.                 strcpy(++ptr, find.name);
  62.             else
  63.                 strcpy(try, find.name);
  64.             return 1;
  65.         }
  66.         while (_dos_findnext(&find) == 0)
  67.         {
  68.             if (find.attrib & _A_SUBDIR)
  69.             {
  70.                 ptr = strrchr(try, '\\');
  71.                 if (ptr != (char *)NULL)
  72.                     strcpy(++ptr, find.name);
  73.                 else
  74.                     strcpy(try, find.name);
  75.                 return 1;
  76.             }
  77.         }
  78.     }
  79.     if (try[strlen(try)-2] == ':' && try[strlen(try)-1] == '.')
  80.     {
  81.         try[strlen(try)-1] = '\\';
  82.         return 1;
  83.     }
  84.     return 0;
  85. }
  86.  
  87. /* ######################## ISABSOLUTEPATH ################### */
  88. int isabsolutepath(char try[])
  89. {
  90.     return strchr("\\/", try[0]) != NULL ||
  91.         (try[1] == ':' && strchr("\\/", try[2]) != NULL);
  92. }
  93.  
  94. /* ###################### KCD ##################### */
  95. int main (int argc, char *argv[])
  96. {
  97.     char *cdpath, dir[MAX_DIR], *nxt, drv='\0', *check,
  98.             try[MAX_DIR], *ptr, root[MAX_DIR];
  99.     unsigned orig_drive, trg_drive, tmp;
  100.     int fnd, cdpathno = 0;
  101.  
  102.     /* get current default drive */
  103.     _dos_getdrive (&orig_drive);
  104.     strcpy(root, "c:\\");
  105.     root[0] = 'a' + orig_drive - 1;
  106.  
  107.     if (argc == 1)
  108.     {
  109.         /* if no arguments, print current directory */
  110.         getcwd(dir, MAX_DIR);
  111.         strlwr(dir);
  112.         printf("%s\n", dir);
  113.         return 0;
  114.     }
  115.  
  116.     strcpy (try, argv[1]);
  117.     if (try[0] == '-')
  118.             strcpy(dir, getenv("LASTDIR"));
  119.     else
  120.     {
  121.         while ((ptr = strchr(try, '/')) != (char *)NULL) *ptr = '\\';
  122.         if (try[strlen(try)-1] == ':')
  123.             strcat (try, ".");
  124.         if ((cdpath = getenv(CDPATH)) == NULL ||
  125.             isdir(try) || isabsolutepath(try) ||
  126.             try[0] == '.')
  127.  
  128.         /*
  129.          * if either cdpath not defined, valid subdir given, or ".." used in
  130.          * relative path, don't bother searching cdpath
  131.         */
  132.             strcpy (dir, try);
  133.         else
  134.         {
  135.             strcpy (dir, ".\\");
  136.             strcat (dir, try);
  137.  
  138.             do
  139.             {
  140.                 root[3] = '\0';
  141.                 /*
  142.                  * if dir given on command line is subdirectory of current directory,
  143.                  * no need to search cdpath
  144.                  */
  145.                 if (!isdir(dir) &&
  146.                     ((nxt = strtok(cdpath, ";")) != NULL))
  147.                 {
  148.                     /* if drive is part of dir, save */
  149.                     if ((check = strchr(try, ':')) != NULL)
  150.                     {
  151.                         drv = *(check-1);
  152.                         check++;
  153.                     }
  154.                     else
  155.                         check = try;
  156.  
  157.                     strcat(root, try);
  158.                     fnd = isdir(root);
  159.                     /*
  160.                      * search each entry in cdpath (left to right) to find first for
  161.                      * which argv[1] is a subdirectory or until cdpath exhausted
  162.                      */
  163.                     do
  164.                     {
  165.                         if (fnd)
  166.                         {
  167.                             strcpy(dir, root);
  168.                             break;
  169.                         }
  170.                         strcpy(dir, nxt);
  171.                         if (dir[strlen(dir)-1] != '\\')
  172.                             strcat(dir, "\\");
  173.                         strcat(dir, check);
  174.                         if(isdir(dir) &&
  175.                             (drv == '\0' || strchr(dir, ':') == NULL
  176.                             ||  drv == dir[0]))
  177.                             fnd = 1;
  178.                     }
  179.                     while(!fnd && ((nxt = strtok(NULL, ";")) != NULL));
  180.                 }
  181.                 cdpathno++;
  182.                 if (!fnd) sprintf(cdpath, "CDPATH%d", cdpathno);
  183.             }
  184.             while(!fnd && ((cdpath = getenv(cdpath)) != (char *)NULL));
  185.  
  186.             /* print error if directory not found in cdpath */
  187.             if (!fnd)
  188.             {
  189.                 fprintf (stderr, "%s: Directory %s not found.\n", PROG, argv[1]);
  190.                 return -1;
  191.             }
  192.         }
  193.     }
  194.  
  195.     /*
  196.      * if directory ends in '\' and is NOT the root directory of a drive, strip
  197.      * off the '\'
  198.      */
  199.     if((dir[strlen(dir)-1] == '\\' || dir[strlen(dir)-1] == '/') &&
  200.         !is_root_dir(dir))
  201.         dir[strlen(dir)-1] = '\0';
  202.  
  203.     /*
  204.      * if drive is part of target directory and it differs from the current
  205.      * default, set drive before performing chdir
  206.      */
  207.     if (strchr(dir, ':') != NULL &&
  208.         (trg_drive = dir[0] + 1 - (isupper(dir[0]) ? 'A' : 'a')) != orig_drive)
  209.             _dos_setdrive(trg_drive, &tmp);
  210.     while (strncmp(dir, "...", 3) == 0)
  211.     {
  212.         getcwd(try, MAX_DIR);
  213.         if (is_root_dir(try) == 0)
  214.                 chdir("..");
  215.         strcpy(dir, dir + 1);
  216.     }
  217.     getcwd(try, MAX_DIR);
  218.     if (is_root_dir(try) && (strcmp(dir, "..") == 0)) return 0;
  219.  
  220.     if (chdir(dir) != 0)
  221.     {
  222.         fprintf (stderr, "%s: Invalid directory %s.\n", PROG, argv[1]);
  223.         exit (1);
  224.     }
  225.     return 0;
  226. }
  227.